﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common;
using DecentralizedModel.Utility;
using System.Threading;
using System.Diagnostics;
using TwoItems.Utility;

namespace DecentralizedModel
{
    public partial class Decentralized : Form
    {
        //误差接受上限
        private double tolerences = 0.01;
        //连续误差可以接受的次数
        private int repeatTimes = 10;
        private int maxIteration = 1000;

        public Decentralized()
        {
            InitializeComponent();
        }

        private BackgroundWorker bgWorker;
        private void btnStart_Click(object sender, EventArgs e)
        {
            //double q = Convert.ToDouble(textBox1.Text);
            //textBox2.Text = NormDistHelper.PNorm(q).ToString();

            tolerences = Convert.ToDouble(tbxTolerence.Text);
            repeatTimes = Convert.ToInt32(tbxRepeatTimes.Text);
            maxIteration = Convert.ToInt32(tbxMaxIteration.Text);

            //循环取出来数据进行计算,后台线程去跑这个程序
            bgWorker = new BackgroundWorker();
            bgWorker.DoWork += CalculateWork;
            bgWorker.ProgressChanged += ShowProgress;
            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;

            bgWorker.RunWorkerAsync();



        }

        private void ShowProgress(object sender, ProgressChangedEventArgs e)
        {
            lblPercentage.Text = e.ProgressPercentage.ToString() + " %";

            lblCurrent.Text = string.Format("{0}/{1}", e.UserState, 10000);

            progressBar1.Value = e.ProgressPercentage;
        }

        private void CalculateWork(object sender, DoWorkEventArgs e)
        {
            int start = Convert.ToInt32(tbxIdStart.Text);
            int end = Convert.ToInt32(tbxIdEnd.Text);

            //依次读取数据
            for (int i = start; i <= end; i++)
            {
                Trace.WriteLine(string.Format("开始算例 DataCount={0}", i));
                bgWorker.ReportProgress((100 * (i - start)) / (end - start + 1), i);

                //读取access 填充ExampleInfo
                ExampleInfo example = DataGateWay.Get(i);

                


            }

            MessageBox.Show("Job is done!!");
        }

        /// <summary>
        /// 一次迭代
        /// </summary>
        /// <param name="example"></param>
        /// <returns>误差e^2</returns>
        private double IterateOnce(ExampleInfo example)
        {
            //todo:此处写成循环赋值，方便以后更多产品的情况
            double variance1 = Math.Pow(example.SD1, 2);
            double variance2 = Math.Pow(example.SD2, 2);

            //计算有效需求的期望和标准差
            double pnorm1 = NormDistHelper.PNorm(example.QD1, example.E1, example.SD1);
            double gama1 = pnorm1 + (example.QD1 * (1 - pnorm1) - (variance1) * NormDistHelper.DNorm(example.QD1, example.E1, example.SD1)) / example.E1;

            double pnorm2 = NormDistHelper.PNorm(example.QD2, example.E2, example.SD2);
            double gama2 = pnorm2 + (example.QD2 * (1 - pnorm2) - variance2 * NormDistHelper.DNorm(example.QD2, example.E2, example.SD2)) / example.E2;

            double e1_e = example.E1 - example.R21 * example.E2 * (1 - gama2);//有效需要的期望
            double sd1_e = Math.Sqrt(variance1 + Math.Pow(example.R21 * example.SD2 * (1 - gama2), 2));//有效需要的标准差

            double e2_e = example.E2 - example.R12 * example.E1 * (1 - gama1);//有效需要的期望
            double sd2_e = Math.Sqrt(variance2 + Math.Pow(example.R12 * example.SD1 * (1 - gama1), 2));//有效需要的标准差


            double nextQd1 = NormDistHelper.QNorm(example.U1 / (example.U1 + example.O1), e1_e, sd1_e);
            double nextQd2 = NormDistHelper.QNorm(example.U2 / (example.U2 + example.O2), e2_e, sd2_e);

            //判断误差Error

            //计算出来的概率
            double prob1_e = NormDistHelper.PNorm(example.QD1, e1_e, sd1_e);
            double prob2_e = NormDistHelper.PNorm(example.QD2, e2_e, sd2_e);
            //待对比的概率
            double prob1_target = example.U1 / (example.U1 + example.O1);
            double prob2_target = example.U2 / (example.U2 + example.O2);

            example.Prob1 = prob1_e;
            example.Prob2 = prob2_e;




            example.QD1 = nextQd1;
            example.QD2 = nextQd2;


            //已经推导出来利润

            double u1 = example.U1;
            double o1 = example.O1;
            double e1 = e1_e;
            double sd1 = sd1_e;
            double q1 = example.QD1;


            example.PD1 = (u1 + o1) *
                          ((e1 - q1) * NormDistHelper.PNorm(q1, e1, sd1) - sd1 * sd1 * NormDistHelper.DNorm(q1, e1, sd1)) +
                          u1 * q1;

            double u2 = example.U2;
            double o2 = example.O2;
            double e2 = e2_e;
            double sd2 = sd2_e;
            double q2 = example.QD2;
            example.PD2 = (u2 + o2) *
                          ((e2 - q2) * NormDistHelper.PNorm(q2, e2, sd2) - sd2 * sd2 * NormDistHelper.DNorm(q2, e2, sd2)) +
                          u2 * q2;

            example.PD = example.PD1 + example.PD2;


            return Math.Pow(Math.Abs(prob1_e - prob1_target) / prob1_target, 2) +
                   Math.Pow(Math.Abs(prob2_e - prob2_target) / prob2_target, 2);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            lblPercentage.Text = string.Empty;
            lblCurrent.Text = string.Empty;
        }
    }
}
